/**
 * create by zhangpu
 * date:2015年3月12日
 */
package com.acooly.module.openapi.client.provider.yinsheng.marshall;

import com.acooly.core.utils.Reflections;
import com.acooly.core.utils.Strings;
import com.acooly.module.openapi.client.api.anotation.ApiItem;
import com.acooly.module.openapi.client.api.exception.ApiClientException;
import com.acooly.module.openapi.client.api.marshal.ApiUnmarshal;
import com.acooly.module.openapi.client.api.message.MessageFactory;
import com.acooly.module.openapi.client.provider.yinsheng.YinShengConstants;
import com.acooly.module.openapi.client.provider.yinsheng.domain.YinShengNotify;
import com.acooly.module.openapi.client.provider.yinsheng.enums.YinShengServiceEnum;
import com.acooly.module.openapi.client.provider.yinsheng.partner.YinShengPartnerIdLoadManager;
import com.acooly.module.openapi.client.provider.yinsheng.support.YinShengRespCodes;
import com.acooly.module.openapi.client.provider.yinsheng.utils.SignUtils;
import com.acooly.module.safety.Safes;
import com.acooly.module.safety.key.KeyLoadManager;
import com.acooly.module.safety.signature.SignTypeEnum;
import com.acooly.module.safety.support.KeyStoreInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.Set;

/**
 * @author zhangpu
 */
@Service
public class YinShengNotifyUnmarshall extends YinShengMarshallSupport
        implements ApiUnmarshal<YinShengNotify, Map<String, String>> {
    private static final Logger logger = LoggerFactory.getLogger(YinShengNotifyUnmarshall.class);
    @Resource(name = "yinShengMessageFactory")
    private MessageFactory messageFactory;

    @Resource(name = "yinShengPartnerIdLoadManager")
    private YinShengPartnerIdLoadManager partnerIdLoadManager;

    @Autowired
    private KeyLoadManager keyStoreLoadManager;

    @SuppressWarnings("unchecked")
    @Override
    public YinShengNotify unmarshal(Map<String, String> message, String serviceName) {
        try {
            logger.info("异步通知{}", message);
            String signature = message.get(YinShengConstants.SIGN);
            message.remove(YinShengConstants.SIGN);
            String plain = SignUtils.getSignContent(message);
            String parnerId = partnerIdLoadManager.load(message.get(YinShengConstants.ORDER_NO_NAME));
            KeyStoreInfo keyStoreInfo = keyStoreLoadManager.load(parnerId,YinShengConstants.PROVIDER_NAME);
            Safes.getSigner(SignTypeEnum.Cert).verify(plain,keyStoreInfo,signature);
            return doUnmarshall(message, serviceName);
        } catch (Exception e) {
            throw new ApiClientException("异步通知 解析失败:" + e.getMessage());
        }

    }

    protected YinShengNotify doUnmarshall(Map<String, String> message, String serviceName) {
        YinShengNotify notify = (YinShengNotify) messageFactory.getNotify(serviceName);
        Set<Field> fields = Reflections.getFields(notify.getClass());
        String key = null;
        for (Field field : fields) {
            ApiItem apiItem = field.getAnnotation(ApiItem.class);
            if (apiItem != null && Strings.isNotBlank(apiItem.value())) {
                key = apiItem.value();
            }else {
                key = field.getName();
            }
            Reflections.invokeSetter(notify, field.getName(), message.get(key));
        }
        notify.setMethod(YinShengServiceEnum.findByKey(serviceName).getCode());
        if (Strings.isNotBlank(notify.getCode())) {
            notify.setMessage(YinShengRespCodes.getMessage(notify.getCode()));
        }
        return notify;
    }

    public void setMessageFactory(MessageFactory messageFactory) {
        this.messageFactory = messageFactory;
    }

}
